"""
@file: news_api.py
@author：wang
@time: 2022/2/23 0023 10:28
"""
import logging
from flask import Blueprint, g
from flask_restful import Api, Resource, fields, marshal_with, reqparse, marshal
from apps.models.news_models import *
from apps.util import login_required

news_bp = Blueprint("news", __name__)

api = Api(news_bp)


# 编辑接口展示内容
news_type_fields = {
    "id": fields.Integer,
    "name": fields.String(attribute="type_name")
}

new_type_parser = reqparse.RequestParser()
new_type_parser.add_argument("name", type=str, help="必须添加新闻类型名称", required=True, location="form")

# 修改的传入
update_type_parser = new_type_parser.copy()
update_type_parser.add_argument("id", type=int, required=True, help="必须添加要修改的类型id")

# 删除的传入
delete_parser = reqparse.RequestParser()
delete_parser.add_argument("id", type=int, required=True, help="必须添加要修改的类型id")


# 新闻类型API
class NewsTypeApi(Resource):
    @marshal_with(news_type_fields)
    def get(self):
        types = NewType.query.all()
        return types

    # 添加新的新闻类型
    def post(self):
        # 获取前端传入内容
        args = new_type_parser.parse_args()
        news_type_name = args.get("name")
        # 数据库添加
        new_Type = NewType()
        new_Type.type_name = news_type_name
        db.session.add(new_Type)
        db.session.commit()
        return marshal(new_Type, news_type_fields)

    # 修改新闻类型名称
    def patch(self):
        args = update_type_parser.parse_args()
        id = args.get("id")
        name = args.get("name")
        new_type_obj = NewType.query.get(id)
        if new_type_obj:
            new_type_obj.type_name = name
            db.session.commit()
            data = {
                "status": 200,
                "msg": "修改成功",
                "type": marshal(new_type_obj, news_type_fields)
            }
            return data
        else:
            return {"status": 400, "msg": "类型查找失败"}

    # 删除新闻类型名称
    def delete(self):
        args = delete_parser.parse_args()
        new_id = args.get("id")
        news_obj = NewType.query.get(new_id)
        if news_obj:
            db.session.delete(news_obj)
            db.session.commit()
            return {"status": 200, "msg": "删除成功", "type_ovj": marshal(news_obj, news_type_fields)}
        else:
            return {"status": 400, "msg": "对象不存在"}


# 传入
news_parser = reqparse.RequestParser()
news_parser.add_argument("typeid", type=int, help="必须添加新闻类型id", required=True)
news_parser.add_argument("page", type=int)
# 输出的格式
"""
{
    "has_more":true,
    'data':[],
    "return_content':0,
    "html":null
}
"""


# 自定义类型------返回用户名称
class AuthorName(fields.Raw):
    def format(self, value):
        return value.username


# 每条新闻的格式
news_fields = {
    "id": fields.Integer,
    "title": fields.String,
    "desc": fields.String,
    "datatime": fields.DateTime(attribute="data_time"),
    "author": AuthorName(attribute="author"),
    "url": fields.Url("news.newsdetail"),
}


# 获取分类下的新闻
class NewsListApi(Resource):
    # 获取某个新闻分类下的新闻
    def get(self):
        args = news_parser.parse_args()
        typeid = args.get("typeid")
        page = args.get("page", 1)
        pagination = News.query.filter(News.news_type_id == typeid).paginate(page=page, per_page=8)
        data = {
            "has_more": pagination.has_next,  # 是否存在下一页
            'data': marshal(pagination.items, news_fields),
            "return_content": len(pagination.items),  # 返回总条数
            "html": "null",
        }

        return data


# 评价回复的格式
reply_fields = {
    "user": AuthorName(attribute='user'),
    "content": fields.String,
    "datetime": fields.DateTime(attribute="data_time"),
    "lovenumber": fields.Integer(attribute="love_num"),
}

# 评价的格式
comment_fields = {
    "user": AuthorName(attribute='user'),
    "content": fields.String,
    "datetime": fields.DateTime(attribute="data_time"),
    "lovenumber": fields.Integer(attribute="love_num"),
    "replys": fields.List(fields.Nested(reply_fields))
}

# 新闻的详情
news_detail_fields = {
    "id": fields.Integer,
    "title": fields.String,
    "content": fields.String,
    "datetime": fields.DateTime(attribute="data_time"),
    "author": AuthorName(attribute="author"),
    # comments和数据中关联字段名称相同
    "comments": fields.List(fields.Nested(comment_fields))

}


class NewsDetailApi(Resource):
    @marshal_with(news_detail_fields)
    def get(self, id):
        news = News.query.get(id)
        return news


"""
添加新闻
"""

# 新闻传入信息
add_news_parser = reqparse.RequestParser()
add_news_parser.add_argument("title", type=str, help="必须填入新闻标题", required=True)
add_news_parser.add_argument("content", type=str, required=True, help="必须填入新闻主体内容")
add_news_parser.add_argument("typeid", type=int, required=True, help="必须填入新闻类型")

# 修改新闻
update_news_parser = add_news_parser.copy()
update_news_parser.add_argument("newsid", type=int, help="必须填入新闻id", required=True)

# 删除新闻
delete_news_parser = reqparse.RequestParser()
delete_news_parser.add_argument("id", type=int, help="必须填入新闻id", required=True)


class NewApi(Resource):
    # login_required 进行用户登录校验，是否存在token令牌
    @login_required
    def post(self):
        args = add_news_parser.parse_args()
        title = args.get("title")
        content = args.get("content")
        typeid = args.get("typeid")
        # 数据库添加
        news = News()
        news.title = title
        news.content = content
        news.desc = content[:10] + "...."
        news.news_type_id = typeid
        news.user_id = g.user.id
        db.session.add(news)
        db.session.commit()
        data = {
            "status": 200,
            "msg": "新闻发布成功",
            "news": marshal(news, news_detail_fields)
        }
        return data

    @login_required
    def patch(self):
        args = update_news_parser.parse_args()
        id = args.get("newsid")
        title = args.get("title")
        content = args.get("content")
        typeid = args.get("typeid")
        news_obj = News.query.get(id)

        if news_obj:
            news_obj.title = title
            news_obj.content = content
            news_obj.desc = content[:10] + "...."
            news_obj.typeid = typeid
            news_obj.user_id = g.user.id
            db.session.commit()
            data = {
                "status": 200,
                "msg": "新闻发布成功",
                "news": marshal(news_obj, news_detail_fields)
            }
            return data
        else:
            return {"status": 401, "msg": "文章不存在"}

    def put(self):
        pass

    @login_required
    def delete(self):
        args = delete_news_parser.parse_args()
        newsid = args.get("id")
        new_obj = News.query.get(newsid)
        if new_obj:
            db.session.delete(new_obj)
            db.session.commit()
            return {"status": 200, "msg": "新闻删除成功！"}
        else:
            return {"status": 400, "msg": "此新闻不存在"}


api.add_resource(NewsTypeApi, "/type")
api.add_resource(NewsListApi, "/newslist")
api.add_resource(NewsDetailApi, "/newsdetail/<int:id>", endpoint="newsdetail")
api.add_resource(NewApi, "/news")
